package com.qding.park.manager.web.controller;

import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.qding.park.common.core.annotation.log.OperationLogType;
import com.qding.park.common.core.annotation.log.SystemControllerLog;
import com.qding.park.common.core.exceptions.ExceptionMessage;
import com.qding.park.common.core.exceptions.system.SystemUnKnown;
import com.qding.park.common.core.validate.RchlValidateBean;
import com.qding.park.common.core.validate.RchlValidateTools;
import com.qding.park.common.utils.DateUtils;
import com.qding.park.common.utils.export.DataField;
import com.qding.park.common.utils.export.ExportDataSource;
import com.qding.park.common.utils.export.excel.ExcelDataExportor;
import com.qding.park.common.utils.export.excel.MODE;
import com.qding.park.common.web.controller.BaseController;
import com.qding.park.manager.common.pojo.ParkDataResult;
import com.qding.park.manager.common.rest.domain.AnswerMsg;
import com.qding.park.manager.common.rest.domain.AnswerMsgFactoryImpl;
import com.qding.park.manager.common.rest.enums.ResponseCodeEnum;
import com.qding.park.manager.facade.statis.service.ReserveStatisFacade;
import com.qding.park.manager.pojo.PowerInfo;
import com.qding.park.manager.pojo.ReserveParams;
import com.qding.park.manager.pojo.TbReserve;
import com.qding.park.manager.pojo.example.TbReserveExample;
import com.qding.park.manager.pojo.example.TbReserveExample.Criteria;
import com.qding.park.manager.service.statis.biz.ReserveBiz;
import com.qding.park.manager.service.statis.mapper.TbReserveStatisMapper;
import com.qding.park.manager.web.form.ReserveListForm;
import com.qding.park.manager.web.power.Power;

@RestController
@RequestMapping("/reserve")
public class Web_ReserveController extends BaseController {
	private static final Logger _log = LoggerFactory.getLogger(Web_CarController.class);

	/**
	 * @Fields ReserveFacade : TODO（预定有关的业务）
	 */
	@Autowired
	private ReserveStatisFacade reserveFacade;

	@Autowired
	private TbReserveStatisMapper tbReserveMapper;

	@Autowired
	private ReserveBiz reserveBiz;

	/**
	 * params(根据车场id查询) TODO(这里描述这个方法适用条件 – 可选) TODO(这里描述这个方法的执行流程 – 可选)
	 * TODO(这里描述这个方法的使用方法 – 可选) TODO(这里描述这个方法的注意事项 – 可选)
	 *
	 * @Title: params @Description: TODO @param @param parkId @param @return
	 * 设定文件 @return AnswerMsg 返回类型 @throws
	 */
	@Power(visitPark = "#parkId")
	@SystemControllerLog(description = "预定参数查询", operation = OperationLogType.reserve_params)
	@RequestMapping("/params")
	public AnswerMsg params(String parkId) {

		/****** 验证字段 ********/
		RchlValidateBean vb = new RchlValidateBean();
		vb.getRequiredValidate().put("parkId", parkId);

		vb.getIntValidate().put("parkId", parkId);
		RchlValidateTools.validate(vb);
		/**************/
		ParkDataResult dataResult = reserveFacade.reserveParams(Integer.valueOf(parkId));
		AnswerMsg answerMsg = AnswerMsgFactoryImpl.createAnswerMsg(dataResult.getData());
		return answerMsg;
	}

	/**
	 * params_set(设置预定参数) TODO(这里描述这个方法适用条件 – 可选) TODO(这里描述这个方法的执行流程 – 可选)
	 * TODO(这里描述这个方法的使用方法 – 可选) TODO(这里描述这个方法的注意事项 – 可选)
	 *
	 * @Title: params_set @Description: TODO @param @param parkId @param @param
	 * appointmentTime @param @param appointmentFee @param @return 设定文件 @return
	 * AnswerMsg 返回类型 @throws
	 */
	@Power(visitPark = "#parkId")
	@SystemControllerLog(description = "预定参数设置", operation = OperationLogType.reserve_params_set)
	@RequestMapping("/params/set")
	public AnswerMsg params_set(String parkId, String appointmentTime, String appointmentFee) {


		RchlValidateBean vb = new RchlValidateBean();
		vb.getRequiredValidate().put("parkId", parkId);

		vb.getIntValidate().put("parkId", parkId);
		if (!StringUtils.isBlank(appointmentTime)) {
			vb.getIntValidate().put("appointmentTime", appointmentTime);
		}
		if (!StringUtils.isBlank(appointmentFee)) {
			vb.getIntValidate().put("appointmentFee", appointmentFee);
		}
		RchlValidateTools.validate(vb);
		/**************/
		ReserveParams params = new ReserveParams();
		if (!StringUtils.isBlank(appointmentFee)) {
			params.setAppointmentFee(Integer.valueOf(appointmentFee));
		}
		if (!StringUtils.isBlank(appointmentTime)) {
			params.setAppointmentTime(Integer.valueOf(appointmentTime));
		}

		ParkDataResult dataResult = reserveFacade.reserveParams_set(params, Integer.valueOf(parkId));
		AnswerMsg answerMsg = AnswerMsgFactoryImpl.createAnswerMsg(dataResult.getData());
		return answerMsg;
	}

	/**
	 * @param carNum
	 *            车牌
	 * @param parkId
	 *            车场编号
	 * @param jumpPage
	 *            当前页码
	 * @param pageLength
	 *            页长度
	 * @return
	 */
	@Power(visitPark = "#form.getParkId()")
	@SystemControllerLog(description = "预定单列表查询", operation = OperationLogType.reserve_list)
	@RequestMapping("/list")
	public AnswerMsg list(@Valid ReserveListForm form, BindingResult result) {

		/* 解析验证结果 */
		super.analysisValid(result);
		/* 解析验证结果 */

		PowerInfo power = this.getPowerInfo();

		int jumpPageInt = Integer.valueOf(form.getJumpPage());
		int pageLengthInt = Integer.valueOf(form.getPageLength());

		/* 组装统计条件 */

		TbReserveExample example = new TbReserveExample();
		Criteria criteria = example.createCriteria();

		if (!StringUtils.isBlank(form.getCarNum())) {
			// 车牌号
			// criteria.andCarnumEqualTo(carNum);
			criteria.andCarnumLike(form.getCarNum());
		}

		if (!StringUtils.isBlank(form.getParkId())) {
			// 车场编号
			criteria.andParkIdEqualTo(Integer.valueOf(form.getParkId()));
		}
		// //过滤预定单
		// criteria.andReserverTypeIsRes();
		// //已经支付了的订单
		// criteria.andTradeIDIsNotNull();

		if (!power.isAdminIs()) {
			criteria.andParkIdIn(power.getParkList());
		}

		/* 组装统计条件 */

		/***** 统计查询 *******/
		ParkDataResult dataResult = reserveFacade.list(example, jumpPageInt, pageLengthInt);
		AnswerMsg answerMsg = AnswerMsgFactoryImpl.createAnswerMsg(dataResult.getData());
		return answerMsg;
	}

	@Power(visitPark = "#parkId")
	@SystemControllerLog(description = "预定单导出", operation = OperationLogType.reserve_exportExcel)
	@RequestMapping("/exportExcel")
	@ResponseBody
	public AnswerMsg exportExcel(String startTime, String endTime, String parkId) {

		try {
			/****** 验证字段 ********/
			// /**************/
			PowerInfo power = this.getPowerInfo();
			// if (!StringUtils.isBlank(parkId) &&
			// !power.getParkList().contains(Integer.valueOf(parkId))&&!power.isAdminIs())
			// {
			// throw new
			// AuthException(AuthException.TypeEnum.EXCEPTION_AUTH.getId(),
			// null,
			// ExceptionMessage.createExceptionMessage(
			// AuthException.TypeEnum.EXCEPTION_AUTH.getDesc(),
			// this.getUsername()+" 没有此车场的权限", "权限不足:"));
			// }
			final TbReserveExample example = new TbReserveExample();
			Criteria criteria = example.createCriteria();

			if (!StringUtils.isBlank(startTime)) {
				// 缴费开始时间
				criteria.andCreateTimeGreaterThanOrEqualTo(
						DateUtils.parseDate(startTime, DateUtils.DATE_FORMAT_DATETIME));
			}
			if (!StringUtils.isBlank(endTime)) {
				// 缴费开始时间
				criteria.andCreateTimeLessThanOrEqualTo(DateUtils.parseDate(endTime, DateUtils.DATE_FORMAT_DATETIME));
			}

			if (!StringUtils.isBlank(parkId)) {
				criteria.andParkIdEqualTo(parkId);
			}
			if (!power.isAdminIs()) {
				criteria.andParkIdIn(power.getParkList());
			}

			// 过滤预定单
			criteria.andReserverTypeIsRes();
			// 只选择有效的状态
			criteria.andEffectiveStatu();
			// 排序
			example.orderByCreateTimeDesc();

			final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
			final SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			final SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMddHHmmss");
			String filename = "预定单报表_" + sdf2.format(new Date());
			response.setHeader("Content-disposition",
					"attachment; filename=" + URLEncoder.encode(filename + ".xls", "utf-8"));
			OutputStream os = response.getOutputStream();
			DataField[] dataFields = new DataField[9];
			dataFields[0] = new DataField("订单号", "orderNum", 20);
			dataFields[1] = new DataField("订单状态", "orderStatus", 25);
			dataFields[2] = new DataField("用户账号", "tel", 20);
			dataFields[3] = new DataField("预约车牌", "carNum", 10);
			dataFields[4] = new DataField("预约车场", "appointmentParkName", 30);
			dataFields[5] = new DataField("预定押金(元)", "appointmentFee", 20);
			dataFields[6] = new DataField("预定开始时间", "startTime", 20);
			dataFields[7] = new DataField("预定结束时间", "endTime", 20);
			dataFields[8] = new DataField("当前状态", "currentStatus", 40);

			new ExcelDataExportor<Object>(dataFields, new ExportDataSource<Object>() {
				@Override
				public List getData() {
					// 查询统计条件
					List<TbReserve> reservelist = tbReserveMapper.reserveListByExample(example);
					List<Map<String, Object>> lists = new ArrayList<Map<String, Object>>();
					int temp = 0;
					for (int i = 0; i < reservelist.size(); i++) {
						Map<String, Object> mapParam = new HashMap<String, Object>();
						TbReserve tbReserve = reservelist.get(i);
						temp = i;
						mapParam.put("orderNum", tbReserve.getId());
						mapParam.put("orderStatus", reserveBiz.getOrderStatusStr(tbReserve));
						mapParam.put("tel", tbReserve.getTel());
						mapParam.put("carNum", tbReserve.getCarNum());
						mapParam.put("appointmentParkName", tbReserve.getParkName());
						// 计算押金
						// tbReserve.setDeposit(reserveBiz.getOrderFee(tbReserve));
						mapParam.put("appointmentFee", tbReserve.getDeposit() / 100);
						// 预定开始时间
						mapParam.put("startTime", tbReserve.getStartTime() == null ? ""
								: DateUtils.formatDate(tbReserve.getStartTime(), DateUtils.DATE_FORMAT_DATETIME));
						// 预定结束时间
						mapParam.put("endTime", tbReserve.getEndTime() == null ? ""
								: DateUtils.formatDate(tbReserve.getEndTime(), DateUtils.DATE_FORMAT_DATETIME));
						mapParam.put("currentStatus", reserveBiz.getCurrentStatus(tbReserve));
						lists.add(mapParam);
					}
					return lists;
				}
			}, os, MODE.EXCEL).export();

			AnswerMsg answerMsg = AnswerMsgFactoryImpl.createAnswerMsg(null);
			return answerMsg;
		} catch (Exception e) {
			SystemUnKnown ex = new SystemUnKnown(e, ExceptionMessage.createExceptionMessage(SystemUnKnown.default_Name,
					"未知Exception", "payStartTime=" + startTime + ",payEndTime=" + endTime));
			exceptionHandle.handle(ex);
			AnswerMsg answerMsg = AnswerMsgFactoryImpl.createErrorAnserMsg(ResponseCodeEnum.SYSTEM_ERROR);
			return answerMsg;
		}
	}
}
